package com.hunttown.mes.manage.controller._lbs;

import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.rpc.domain.*;
import com.hunttown.mes.rpc.domain.query.LbsPointDTOQuery;
import com.hunttown.mes.rpc.domain.query.LbsTerminalDTOQuery;
import com.hunttown.mes.rpc.domain.query.LbsTrackDTOQuery;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.common.utils.DateConvertUtils;
import com.hunttown.mes.common.utils.FormatUtils;
import com.hunttown.mes.common.utils.RelativeFrontDateUtils;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.manage.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @title: 轨迹回放
 * @author: wangjunfu
 * @date: 2021年10月07日 17:17
 * @description:
 */
@Controller
@RequestMapping(value = "/lbs-trace")
public class TraceController {

    private final AnalysisWebsiteParamManageService websiteService;
    private final AnalysisManageManageService manageService;
    private final LbsTerminalManageService lbsTerminalService;
    private final LbsTerminalStateManageService lbsTerminalStateService;
    private final LbsTrackManageService lbsTrackService;
    private final LbsPointManageService lbsPointService;
    private final TransportUserManageService userService;

    @Autowired
    public TraceController(AnalysisWebsiteParamManageService websiteService, AnalysisManageManageService manageService, LbsTerminalManageService lbsTerminalService, LbsTerminalStateManageService lbsTerminalStateService, LbsTrackManageService lbsTrackService, LbsPointManageService lbsPointService, TransportUserManageService userService) {
        this.websiteService = websiteService;
        this.manageService = manageService;
        this.lbsTerminalService = lbsTerminalService;
        this.lbsTerminalStateService = lbsTerminalStateService;
        this.lbsTrackService = lbsTrackService;
        this.lbsPointService = lbsPointService;
        this.userService = userService;
    }

    //region 配置中的高德信息
    @Value("${amap.key}")
    private String amapKey;

    @Value("${amap.version}")
    private String amapVersion;
    //endregion

    //region 终端查询

    /**
     * 终端查询
     *
     * @param request req
     * @param model   model
     * @return vm
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(HttpServletRequest request, Model model) {

        model.addAttribute("amapKey", amapKey);
        model.addAttribute("amapVersion", amapVersion);

        //取出所有的终端
        LbsTerminalDTOQuery terminalQuery = new LbsTerminalDTOQuery();
        terminalQuery.setPageSize(1000);
        terminalQuery.setStopFlag(0);
        Page<LbsTerminalDTO> terminalPage = lbsTerminalService.getForPage(terminalQuery);

        //中心点
        String centerPosition = "";

        //要显示的终端列表
        List<Map<String, String>> pointList = new ArrayList<>();

        //复选菜单列表
        List<String> checkboxList = new ArrayList<>();
        checkboxList.add("<ul>");
        checkboxList.add("<li data-jstree='{\"opened\":true, \"icon\":\"md-home\"}' terminalId='0'>" +
                "<a href='javascript:void(0);' class='text-bold' onclick='showTerminalLocation(0)'>终端</a>");

        checkboxList.add("<ul>");

        //取出最近的轨迹
        for (LbsTerminalDTO item : terminalPage.getItems()) {

            //取出新的坐标
            LbsTerminalStateDTO pointObj = lbsTerminalStateService.getByTerminalId(item.getId());

            if (pointObj != null) {
                String frontDate = RelativeFrontDateUtils.format(pointObj.getLastUpdateTime());

                //要显示的坐标点
                Map<String, String> map = new HashMap<>();
                map.put("name", item.getTerminalName().split("的")[0]);
                map.put("x", pointObj.getLongitude());
                map.put("y", pointObj.getLatitude());
                map.put("timeSr", pointObj.getLastUpdateTimeSr());
                map.put("time", frontDate);
                //pointList.add(map);（默认不显示，选择后显示）

                //是否选中（默认不选中）
                String chkSign = ", \"selected\":false";

                //是否显示绿色
                String classTxt = "";
                if (frontDate.contains("秒") || frontDate.contains("分钟")) {
                    classTxt = "text-success";
                }

                //是否显示离线
                String statusTxt = "";
                if (classTxt.equals("")) {
                    statusTxt = "离线-";
                }

                //左树
                checkboxList.add("<li class='" + classTxt + "' data-jstree='{\"opened\":true, \"icon\":\"md-room\"" + chkSign + "}' terminalId='" + item.getId() + "'>" +
                        "<a href='javascript:void(0);' onclick='showTerminalLocation(" + item.getId() + ")'>" + map.get("name") + "[" + statusTxt + frontDate + "]</a>");

                checkboxList.add("</li>");

                //中心点（默认没有中心点，取浏览器本身的坐标）
                //if (StringUtils.isBlank(centerPosition)) {
                //    centerPosition = pointObj.getLongitude() + "," + pointObj.getLatitude();
                //}
            }
        }
        checkboxList.add("</ul>");
        checkboxList.add("</li>");
        checkboxList.add("</ul>");

        model.addAttribute("checkboxList", checkboxList);
        model.addAttribute("pointList", pointList);
        model.addAttribute("centerPosition", centerPosition);

        //网站名称
        String pin = AdminBaseClass.getPin(request);
        model.addAttribute("websiteName", websiteService.getWebsiteNameFromCache(request, pin));

        //姓名
        String nick = AdminBaseClass.getNick(request);
        model.addAttribute("cnName", nick);

        AnalysisManageDTO admindto = manageService.getFromCacheNickname(nick);
        model.addAttribute("headNumer", admindto.getHeadPicNumber());

        return "lbs/trace/index";
    }
    //endregion

    //region 终端查询（ajax）

    /**
     * 终端查询（ajax）
     *
     * @param selectTerminals 已选中的终端
     * @param clickTerminal   点击的终端
     * @return json
     */
    @RequestMapping(value = "/getLocationPoint", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> getLocationPoint(String selectTerminals, Integer clickTerminal) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);
        map.put("returnMessage", "数据获取异常！");

        List<Integer> terList = FormatUtils.commaToList_Integer(selectTerminals);
        if (terList.size() == 0) {
            return map;
        }

        //取出所有的终端
        LbsTerminalDTOQuery terminalQuery = new LbsTerminalDTOQuery();
        terminalQuery.setPageSize(1000);
        terminalQuery.setStopFlag(0);
        Page<LbsTerminalDTO> terminalPage = lbsTerminalService.getForPage(terminalQuery);

        //中心点
        String centerPosition = "";

        //要显示的终端列表
        List<Map<String, String>> pointList = new ArrayList<>();

        //选中的终端数据
        Map<String, Object> selectmap = new HashMap<>();

        //取出最近的轨迹
        for (LbsTerminalDTO item : terminalPage.getItems()) {
            if (!terList.contains(item.getId())) {
                continue;
            }

            LbsTrackDTO trackObj = lbsTrackService.getByTerminalId(item.getId());

            //取出新的坐标
            if (trackObj != null) {
                LbsTerminalStateDTO pointObj = lbsTerminalStateService.getByTerminalId(item.getId());

                if (pointObj != null) {
                    String frontDate = RelativeFrontDateUtils.format(pointObj.getLastUpdateTime());

                    Map<String, String> temp = new HashMap<>();
                    temp.put("name", item.getTerminalName().split("的")[0]);
                    temp.put("x", pointObj.getLongitude());
                    temp.put("y", pointObj.getLatitude());
                    temp.put("time", frontDate);
                    temp.put("timeSr", pointObj.getLastUpdateTimeSr());
                    pointList.add(temp);

                    if (item.getId().equals(clickTerminal)) {
                        selectmap.put("name", temp.get("name"));
                        selectmap.put("code", trackObj.getTrackCode());
                        selectmap.put("timeSr", pointObj.getLastUpdateTimeSr());

                        //是否在线
                        if (frontDate.contains("秒") || frontDate.contains("分钟")) {
                            selectmap.put("status", 1);
                            selectmap.put("statusName", "在线");
                        } else {
                            selectmap.put("status", 0);
                            selectmap.put("statusName", "离线");
                        }

                        //手机号
                        selectmap.put("mobile", "");
                        TransportUserDTO user = userService.getById(trackObj.getUserId());
                        if (user != null) {
                            selectmap.put("mobile", user.getMobile());
                        }

                        //最新位置
                        selectmap.put("lng", pointObj.getLongitude());
                        selectmap.put("lat", pointObj.getLatitude());

                        //中心点
                        centerPosition = pointObj.getLongitude() + "," + pointObj.getLatitude();
                    }

                    //中心点
                    if (StringUtils.isBlank(centerPosition)) {
                        centerPosition = pointObj.getLongitude() + "," + pointObj.getLatitude();
                    }
                }
            }
        }

        map.put("pointList", pointList);
        map.put("centerPosition", centerPosition);
        map.put("selectMap", selectmap);

        map.put("returnCode", 1);
        return map;
    }
    //endregion

    //region 轨迹查看

    /**
     * 轨迹查看
     *
     * @param model      model
     * @param terminalId 终端ID
     * @param trackId    轨迹ID，他决定查询日期
     * @param daterange  时间范围
     * @param frontDay   -1不生效 0今天 1前一天 2后一天
     * @param orderId    工单ID
     * @return vm
     */
    @RequestMapping(value = "/viewTrace", method = RequestMethod.GET)
    public String viewTrace(HttpServletRequest request, Model model, Integer terminalId, Integer trackId, String daterange, Integer frontDay, Integer orderId) {

        model.addAttribute("amapKey", amapKey);
        model.addAttribute("amapVersion", amapVersion);

        //网站名称
        String pin = AdminBaseClass.getPin(request);
        model.addAttribute("websiteName", websiteService.getWebsiteNameFromCache(request, pin));

        //姓名
        String nick = AdminBaseClass.getNick(request);
        model.addAttribute("cnName", nick);

        AnalysisManageDTO admindto = manageService.getFromCacheNickname(nick);
        model.addAttribute("headNumer", admindto.getHeadPicNumber());

        //日期设置
        String startDate = "";
        String endDate = "";

        //工单轨迹查询

        //日期拆解
        if (StringUtils.isNotBlank(daterange)) {
            String[] date = daterange.split("~");
            if (date.length == 2) {
                startDate = date[0].trim();
                endDate = date[1].trim();

                //不能跨天
                if (!startDate.split(" ")[0].equals(endDate.split(" ")[0])) {
                    endDate = startDate.split(" ")[0] + " " + endDate.split(" ")[1];
                }
            }
        }

        //无日期
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            String today = DateConvertUtils.getFetureDate(0);

            //取当前轨迹的日期
            if (trackId != null && trackId > 0) {
                LbsTrackDTO track = lbsTrackService.getById(trackId);
                if (track != null) {
                    today = track.getCreateTimeSr().split(" ")[0];
                }
            }

            startDate = today + " 00:00:00";
            endDate = today + " 23:59:59";
        }

        //不生效，按默认日期查询
        if (frontDay == null) {
            frontDay = -1;
        }

        //1.判断是否是前一天
        if (frontDay == 0) { //今天
            String today = DateConvertUtils.getFetureDate(0);
            startDate = today + " 00:00:00";
            endDate = today + " 23:59:59";
        }

        if (frontDay == 1) { //前一天
            String today = DateConvertUtils.getPastDateAssignDate(startDate, 1);
            startDate = today + " 00:00:00";
            endDate = today + " 23:59:59";
        }

        if (frontDay == 2) { //后一天
            String today = DateConvertUtils.getPastDateAssignDate(startDate, -1);
            startDate = today + " 00:00:00";
            endDate = today + " 23:59:59";
        }

        model.addAttribute("startDate", startDate);
        model.addAttribute("endDate", endDate);

        //无终端可查
        if (terminalId == null || terminalId <= 0) {
            return "lbs/trace/view";
        }
        model.addAttribute("terminalId", terminalId);

        //2.根据tid和日期选择轨迹
        LbsTrackDTOQuery trackQuery = new LbsTrackDTOQuery();
        trackQuery.setTerminalId(terminalId);
        trackQuery.setShowDate(startDate.split(" ")[0]);
        LbsTrackDTO track = lbsTrackService.getByQuery(trackQuery);
        if (track == null) {
            return "lbs/trace/view";
        }

        //3.获取坐标点
        LbsPointDTOQuery pointQuery = new LbsPointDTOQuery();
        pointQuery.setTrackId(track.getId());
        pointQuery.setStartDate(startDate);
        pointQuery.setEndDate(endDate);
        pointQuery.setPageSize(10000);
        Page<LbsPointDTO> lbsPointPage = lbsPointService.getForPage(pointQuery);

        //终端信息
        LbsTerminalDTO terminal = lbsTerminalService.getById(terminalId);
        if (terminal == null) {
            return "lbs/trace/view";
        }

        Map<String, Object> selectmap = new HashMap<>();
        selectmap.put("name", terminal.getTerminalName().split("的")[0]);
        selectmap.put("terminal", terminal.getTerminalName());
        selectmap.put("code", track.getTrackCode());
        selectmap.put("mobile", "");

        TransportUserDTO user = userService.getById(terminal.getUserId());
        if (user != null) {
            selectmap.put("mobile", user.getMobile());
        }

        //最高时速
        BigDecimal speed = BigDecimal.ZERO;

        //距离（两种计算方式）
        int distance = 0;
        BigDecimal mileage = BigDecimal.ZERO;

        //起点坐标
        String startPosition = "";

        //要显示的终端列表
        List<Map<String, String>> pointList = new ArrayList<>();

        //坐标集合
        for (LbsPointDTO item : lbsPointPage.getItems()) {
            if (item.getLongitude().equals("0.0")) {
                continue;
            }

            Map<String, String> temp = new HashMap<>();
            temp.put("x", item.getLongitude());
            temp.put("y", item.getLatitude());
            pointList.add(temp);

            //最高时速
            if (speed.compareTo(item.getSpeed()) < 0) {
                speed = item.getSpeed();
            }

            //总里程
            distance += item.getDistance();

            //起点坐标
            if (StringUtils.isBlank(startPosition)) {
                startPosition = item.getLongitude() + "," + item.getLatitude();
            }
        }

        //中心点
        String centerPosition = startPosition;

        if (pointList.size() > 0) {
            int k = pointList.size() / 2;
            centerPosition = pointList.get(k).get("x") + "," + pointList.get(k).get("y");
        }

        //第一个点
        for (LbsPointDTO item : lbsPointPage.getItems()) {
            selectmap.put("ontime", item.getCreateTimeSr()); //上线时间
            mileage = item.getMileage(); //初始里程
            break;
        }

        //最后一个（不为空）的点
        for (int i = lbsPointPage.getItems().size() - 1; i >= 0; i--) {
            LbsPointDTO item = lbsPointPage.getItems().get(i);

            //最新位置
            if (!item.getLongitude().equals("0.0")) {
                selectmap.put("lng", item.getLongitude());
                selectmap.put("lat", item.getLatitude());
                break;
            }
        }

        //判断是否有最后一个点（理论上只要有轨迹，就肯定有坐标点）
        if (lbsPointPage.getItems().size() > 0) {
            LbsPointDTO lastPoint = lbsPointPage.getItems().get(lbsPointPage.getItems().size() - 1);

            //离线时间
            selectmap.put("offtime", lastPoint.getCreateTimeSr());

            //结束里程
            if (lastPoint.getMileage() != null) {
                mileage = lastPoint.getMileage().subtract(mileage);
            }

            //是否在线
            String frontDate = RelativeFrontDateUtils.format(lastPoint.getCreateTime());
            if (frontDate.contains("秒") || frontDate.contains("分钟")) {
                selectmap.put("status", 1);
                selectmap.put("statusName", "在线");
            } else {
                selectmap.put("status", 0);
                selectmap.put("statusName", "离线");
            }

        } else {
            //没有坐标点，只给默认值
            selectmap.put("offtime", "未知");
            selectmap.put("status", 0);
            selectmap.put("statusName", "离线");
        }

        //两种计算方式，哪个有值用哪个
        if (distance > 0) {
            //米 变 公里
            float km = (float) distance / 1000;
            selectmap.put("distance", FormatUtils.fmt2point(km));
        } else {
            selectmap.put("distance", mileage);
        }

        //米/秒 变 公里/小时（规则修改，数据库存储的即为 千米/时）
        //selectmap.put("speed", FormatUtils.fmtMeToKm(speed.floatValue()));
        selectmap.put("speed", speed);

        model.addAttribute("pointList", pointList);
        model.addAttribute("startPosition", startPosition);
        model.addAttribute("centerPosition", centerPosition);
        model.addAttribute("selectmap", selectmap);

        return "lbs/trace/view";
    }
    //endregion
}
